package cloud.tianai.mate.captcha.generator.impl;

import cloud.tianai.captcha.common.exception.ImageCaptchaException;
import cloud.tianai.captcha.common.util.CollectionUtils;
import cloud.tianai.captcha.generator.ImageTransform;
import cloud.tianai.captcha.generator.common.FontWrapper;
import cloud.tianai.captcha.generator.common.model.dto.*;
import cloud.tianai.captcha.generator.common.util.CaptchaImageUtils;
import cloud.tianai.captcha.interceptor.CaptchaInterceptor;
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.common.model.dto.Resource;
import cloud.tianai.captcha.resource.common.model.dto.ResourceMap;
import lombok.Getter;
import lombok.Setter;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

import static cloud.tianai.mate.captcha.common.constant.MateCaptchaTypeConstant.WORD_ORDER_IMAGE_CLICK;

/**
 * @Author: 天爱有情
 * @date 2022/12/30 10:29
 * @Description 语序点选
 */
public class MateWordOrderClickImageCaptchaGenerator extends AbstractClickImageCaptchaGenerator {

    /** 字体包. */
    @Getter
    @Setter
    protected List<FontWrapper> fonts = new ArrayList<>();
    @Getter
    @Setter
    protected Integer clickImgWidth = 100;
    @Getter
    @Setter
    protected Integer clickImgHeight = 100;
    @Getter
    @Setter
    protected int tipImageInterferenceLineNum = 2;
    @Getter
    @Setter
    protected int tipImageInterferencePointNum = 5;

    public MateWordOrderClickImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager) {
        this(imageCaptchaResourceManager, null, null);
    }

    public MateWordOrderClickImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager,
                                                   ImageTransform imageTransform,
                                                   CaptchaInterceptor interceptor,
                                                   List<FontWrapper> fonts) {
        super(imageCaptchaResourceManager);
        setImageTransform(imageTransform);
        setInterceptor(interceptor);
        this.fonts = fonts;
    }

    public MateWordOrderClickImageCaptchaGenerator(ImageCaptchaResourceManager imageCaptchaResourceManager, ImageTransform imageTransform, CaptchaInterceptor interceptor) {
        super(imageCaptchaResourceManager);
        setImageTransform(imageTransform);
        setInterceptor(interceptor);
    }

    @Override
    protected void doInit() {
        if (CollectionUtils.isEmpty(fonts)) {
            // 使用默认字体
            throw new ImageCaptchaException("初始化语序文字点选验证码失败，请设置字体包后再调用init()");
        }
//        ResourceStore resourceStore = imageCaptchaResourceManager.getResourceStore();
//        // 添加一些系统的资源文件
//        resourceStore.addResource(WORD_ORDER_IMAGE_CLICK, new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/1.jpg"), DEFAULT_TAG));
//
//        ClassPathResourceProvider classPathResourceProvider = new ClassPathResourceProvider();
//        InputStream stream = classPathResourceProvider.getResourceInputStream(new Resource(ClassPathResourceProvider.NAME, DEFAULT_SLIDER_IMAGE_RESOURCE_PATH.concat("/idioms.txt")));
//        Scanner scanner = new Scanner(stream);
//        while (scanner.hasNext()) {
//            String idiom = scanner.nextLine();
//            resourceStore.addTemplate(WORD_ORDER_IMAGE_CLICK, wordToResourceMap(idiom, DEFAULT_TAG));
//        }
//        try {
//            stream.close();
//        } catch (IOException e) {
//            // ignore
//        }
    }

    @Override
    protected List<Resource> randomGetClickImgTips(GenerateParam param) {
        // tipSize = checkClickCount
        ResourceMap resourceMap = getImageResourceManager().randomGetTemplate(WORD_ORDER_IMAGE_CLICK, null);
        List<Resource> tips = new ArrayList<>(resourceMap.values());
        // 打乱
        Collections.shuffle(tips);
        return tips;
    }

    @Override
    public ImgWrapper getClickImg(Resource tip, Color randomColor) {
        FontWrapper fontWrapper = fonts.get(randomInt(fonts.size()));
        Font font = fontWrapper.getFont();
        float currentFontTopCoef = fontWrapper.getCurrentFontTopCoef();
        if (randomColor == null) {
            ThreadLocalRandom random = ThreadLocalRandom.current();
            randomColor = CaptchaImageUtils.getRandomColor(random);
        }
        // 这里和文字点选验证码一样
//        ThreadLocalRandom random = ThreadLocalRandom.current();
        // 随机颜色
//        Color randomColor = CaptchaImageUtils.getRandomColor(random);
        // 随机角度
        int randomDeg = randomInt(0, 85);
        BufferedImage fontImage = CaptchaImageUtils.drawWordImg(randomColor,
                tip.getData(),
                font,
                currentFontTopCoef,
                clickImgWidth,
                clickImgHeight,
                randomDeg);
        return new ImgWrapper(fontImage, tip, randomColor);
    }

    @Override
    protected List<ClickImageCheckDefinition> filterAndSortClickImageCheckDefinition(List<ClickImageCheckDefinition> allCheckDefinitionList) {
        // 还原顺序
        List<ClickImageCheckDefinition> sorted = allCheckDefinitionList.stream().sorted(Comparator.comparingInt(a -> Integer.parseInt(a.getTip().getTag()))).collect(Collectors.toList());
        return sorted;
    }

    @Override
    public ImageCaptchaInfo doWrapImageCaptchaInfo(CaptchaExchange captchaExchange) {
        GenerateParam param = captchaExchange.getParam();
        BufferedImage bgImage = captchaExchange.getBackgroundImage();
        Resource resourceImage = captchaExchange.getResourceImage();
        CustomData data = captchaExchange.getCustomData();
        Object checkClickImageCheckDefinitionList = captchaExchange.getTransferData();
        ImageTransformData transform = getImageTransform().transform(param, bgImage, resourceImage, data);
        ImageCaptchaInfo clickImageCaptchaInfo = new ImageCaptchaInfo();
        clickImageCaptchaInfo.setBackgroundImage(transform.getBackgroundImageUrl());
        clickImageCaptchaInfo.setBackgroundImageTag(resourceImage.getTag());
        clickImageCaptchaInfo.setBackgroundImageWidth(bgImage.getWidth());
        clickImageCaptchaInfo.setBackgroundImageHeight(bgImage.getHeight());
        clickImageCaptchaInfo.setRandomX(null);
        clickImageCaptchaInfo.setTolerant(null);
        clickImageCaptchaInfo.setType(WORD_ORDER_IMAGE_CLICK);
        data.setExpand(checkClickImageCheckDefinitionList);
        clickImageCaptchaInfo.setData(data);
        return clickImageCaptchaInfo;
    }

    public static ResourceMap wordToResourceMap(String wordOrderStr, String tag) {
        ResourceMap templateResource = new ResourceMap(tag, wordOrderStr.length());
        char[] chars = wordOrderStr.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            templateResource.put(String.valueOf(i), new Resource(null, chars[i] + "", String.valueOf(i)));
        }
        return templateResource;
    }
}
